﻿/*
 * @Autor: PK
 * @Date: 2021-03-31 13:34:14
 * @Description: 路网创建、生成中，使用的信息变量等，相当于数据容器
 */

using System.Collections.Generic;
using System.Linq;
using NLog;
using O2DESNet;
using ShkSimulation.core.dao.input.loader;
using ShkSimulation.core.dao.input.resource;
using ShkSimulation.core.exceptions;
using ShkSimulation.core.template.agency;
using ShkSimulation.core.template.customer;
using ShkSimulation.core.template.model;
using ShkSimulation.core.util;

namespace ShkSimulation.core.template {

    public class NetworkEnvironment : NetworkInputData {
        
        protected static readonly Logger logger = LogManager.GetLogger(nameof(NetworkEnvironment));

        public NetworkEnvironment(string configPath, ResourceLoader resourceLoader) 
            : this(InputConfig.ResolveConfig(configPath), resourceLoader) {
        }

        public NetworkEnvironment(InputConfig config, ResourceLoader resourceLoader) {
            this.ConfigInstance = config ?? throw new SimulationInitException("必须包含SystemConfig");
            resourceLoader = resourceLoader ?? throw new SimulationInitException("必须包含resourceLoader");
            // 循环加载Resource
            foreach (var (key, path) in config.ResourcePaths) {
                logger.Info($"属性加载[{key}: {path}]");
                string newKey = key.Replace(InputConfig.DataPathPrefix, string.Empty);
                Resource resource = resourceLoader.LoadData(newKey, path);
                AllData.Add(newKey, resource);
            }
        }
        
        public NetworkEnvironment(NetworkInputData defaultInputData) {
            if (defaultInputData == null) {
                throw new SimulationInitException("NetworkDataInput不能为空");
            }
            logger.Info($"属性复制[{defaultInputData.ConfigInstance}]");
            this.ConfigInstance = new InputConfig();
            this.ConfigInstance.ResourcePaths = new Dictionary<string, string>(defaultInputData.ConfigInstance.ResourcePaths);
            this.ConfigInstance.Configs = new Dictionary<string, object>(defaultInputData.ConfigInstance.Configs);
            this.AllData = defaultInputData.AllResources.ToDictionary(each => each.Key, each => each.Value.Clone());
        }

        protected Dictionary<string, Resource> AllData { get; private set; } = new Dictionary<string, Resource>();
        public InputConfig ConfigInstance { get; private set; }
        public IReadOnlyList<CustomerTemplate> CustomerTemplate { get; set; }
        
        public IReadOnlyDictionary<string, List<Agency>> ClassifiedAgencies { get; set; }
        public IReadOnlyDictionary<int, Agency> AllAgencies { get; set; }

        public void UpdateResource(string table, Resource resource) {
            if (table.StartsWith(InputConfig.DataPathPrefix)) {
                table = table.Replace(InputConfig.DataPathPrefix, string.Empty);
            }
            AllData[table] = resource;
            CustomerTemplate = new List<CustomerTemplate>();
            AllAgencies = new Dictionary<int, Agency>();
            ClassifiedAgencies = new Dictionary<string, List<Agency>>();
            logger.Info($"更新Input属性:{table}, 重置服务台属性");
        }

        public IReadOnlyDictionary<string, Resource> AllResources {
            get {
                return AllData.AsReadOnly();
            }
        }
        
        public NetworkInputData Clone() {
            return new NetworkEnvironment(this);
        }

    }
}
